package com.campusbackend.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campusbackend.entity.NotificationConfirmations;
import com.campusbackend.entity.Notifications;
import com.campusbackend.entity.Students;
import com.campusbackend.entity.Teachers;
import com.campusbackend.entity.Teams;
import com.campusbackend.entity.vo.NotificationConfirmVO;
import com.campusbackend.entity.vo.NotificationCreateVO;
import com.campusbackend.entity.vo.NotificationDetailVO;
import com.campusbackend.entity.vo.NotificationListVO;
import com.campusbackend.mapper.NotificationConfirmationsMapper;
import com.campusbackend.mapper.NotificationsMapper;
import com.campusbackend.mapper.StudentsMapper;
import com.campusbackend.mapper.TeachersMapper;
import com.campusbackend.mapper.TeamExpertsMapper;
import com.campusbackend.mapper.TeamMembersMapper;
import com.campusbackend.mapper.TeamsMapper;
import com.campusbackend.service.NotificationsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 队伍通知表 服务实现类
 * </p>
 *
 * @author yezi
 * @since 2025-07-26
 */
@Slf4j
@Service
public class NotificationsServiceImpl extends ServiceImpl<NotificationsMapper, Notifications> implements NotificationsService {

    @Autowired
    private NotificationConfirmationsMapper confirmationsMapper;

    @Autowired
    private TeamsMapper teamsMapper;

    @Autowired
    private TeamMembersMapper teamMembersMapper;

    @Autowired
    private TeamExpertsMapper teamExpertsMapper;

    @Autowired
    private TeachersMapper teachersMapper;

    @Autowired
    private StudentsMapper studentsMapper;

    @Override
    @Transactional
    public String publishNotification(NotificationCreateVO createVO, Byte publisherType, Long publisherId, String publisherName) {
        try {
            // 验证用户是否为队伍成员
            if (!isTeamMember(createVO.getTeamId(), publisherType, publisherId)) {
                return "您不是该队伍成员，无法发布通知";
            }

            // 获取队伍信息
            Teams team = teamsMapper.selectById(createVO.getTeamId());
            if (team == null) {
                return "队伍不存在";
            }

            // 统计队伍总成员数（包括指导老师）
            int totalMembers = getTotalTeamMembers(createVO.getTeamId());

            // 创建通知
            Notifications notification = new Notifications();
            notification.setTeamId(createVO.getTeamId());
            notification.setPublisherType(publisherType);
            notification.setPublisherId(publisherId);
            notification.setPublisherName(publisherName);
            notification.setTitle(createVO.getTitle());
            notification.setContent(createVO.getContent());

            // 处理图片列表
            if (createVO.getImages() != null && !createVO.getImages().isEmpty()) {
                String imagesJson = JSON.toJSONString(createVO.getImages());
                log.info("保存图片列表 - 原始列表: {}, JSON字符串: {}", createVO.getImages(), imagesJson);
                notification.setImages(imagesJson);
            } else {
                log.info("没有图片需要保存");
                notification.setImages(null);
            }

            notification.setIsUrgent(createVO.getIsUrgent());
            notification.setRequireConfirmation(createVO.getRequireConfirmation());
            notification.setTotalMembers(totalMembers);
            notification.setConfirmedCount(0);
            notification.setStatus((byte) 1);
            notification.setCreateTime(LocalDateTime.now());
            notification.setUpdateTime(LocalDateTime.now());

            // 保存通知
            boolean saved = save(notification);

            if (saved) {
                log.info("通知发布成功 - 通知ID: {}, 发布者: {} ({}), 队伍ID: {}, 图片数据: {}",
                        notification.getId(), publisherName, publisherType == 1 ? "教师" : "学生",
                        createVO.getTeamId(), notification.getImages());

                // 验证保存后的数据
                Notifications savedNotification = getById(notification.getId());
                if (savedNotification != null) {
                    log.info("数据库验证 - 保存后的图片数据: {}", savedNotification.getImages());
                }

                return "通知发布成功";
            } else {
                return "通知发布失败";
            }

        } catch (Exception e) {
            log.error("发布通知异常", e);
            return "发布通知时发生错误：" + e.getMessage();
        }
    }

    @Override
    public List<NotificationListVO> getTeamNotifications(Long teamId, Byte currentUserType, Long currentUserId) {
        try {
            // 验证用户是否为队伍成员
            if (!isTeamMember(teamId, currentUserType, currentUserId)) {
                return new ArrayList<>();
            }

            // 查询队伍通知
            QueryWrapper<Notifications> wrapper = new QueryWrapper<>();
            wrapper.eq("team_id", teamId)
                   .eq("status", 1)
                   .orderByDesc("is_urgent")
                   .orderByDesc("create_time");

            List<Notifications> notifications = list(wrapper);

            // 转换为VO
            return notifications.stream().map(notification -> {
                NotificationListVO vo = new NotificationListVO();
                vo.setId(notification.getId());
                vo.setTeamId(notification.getTeamId());
                vo.setPublisherType(notification.getPublisherType());
                vo.setPublisherId(notification.getPublisherId());
                vo.setPublisherName(notification.getPublisherName());
                vo.setTitle(notification.getTitle());

                // 内容摘要（前100个字符）
                String content = notification.getContent();
                vo.setContentSummary(content.length() > 100 ? content.substring(0, 100) + "..." : content);

                // 处理图片
                if (notification.getImages() != null && !notification.getImages().isEmpty()) {
                    List<String> images = JSON.parseArray(notification.getImages(), String.class);
                    vo.setImageCount(images.size());
                    vo.setFirstImageUrl(images.get(0));
                    vo.setAllImages(images); // 添加所有图片
                } else {
                    vo.setImageCount(0);
                    vo.setAllImages(new ArrayList<>()); // 空列表
                }

                vo.setIsUrgent(notification.getIsUrgent());
                vo.setRequireConfirmation(notification.getRequireConfirmation());
                vo.setTotalMembers(notification.getTotalMembers());
                vo.setConfirmedCount(notification.getConfirmedCount());

                // 计算确认进度
                if (notification.getTotalMembers() > 0) {
                    vo.setConfirmationProgress((double) notification.getConfirmedCount() / notification.getTotalMembers() * 100);
                } else {
                    vo.setConfirmationProgress(0.0);
                }

                // 检查当前用户是否已确认
                vo.setIsConfirmed(isUserConfirmed(notification.getId(), currentUserType, currentUserId));

                vo.setCreateTime(notification.getCreateTime());
                vo.setUpdateTime(notification.getUpdateTime());

                // 获取发布者头像
                vo.setPublisherAvatar(getPublisherAvatar(notification.getPublisherType(), notification.getPublisherId()));

                // 获取队伍名称
                Teams team = teamsMapper.selectById(teamId);
                vo.setTeamName(team != null ? team.getTeamName() : "");

                return vo;
            }).collect(Collectors.toList());

        } catch (Exception e) {
            log.error("获取队伍通知列表异常", e);
            return new ArrayList<>();
        }
    }

    @Override
    public NotificationDetailVO getNotificationDetail(Long notificationId, Byte currentUserType, Long currentUserId) {
        try {
            Notifications notification = getById(notificationId);
            if (notification == null || notification.getStatus() == 0) {
                return null;
            }

            // 验证用户是否为队伍成员
            if (!isTeamMember(notification.getTeamId(), currentUserType, currentUserId)) {
                return null;
            }

            NotificationDetailVO vo = new NotificationDetailVO();
            vo.setId(notification.getId());
            vo.setTeamId(notification.getTeamId());
            vo.setPublisherType(notification.getPublisherType());
            vo.setPublisherId(notification.getPublisherId());
            vo.setPublisherName(notification.getPublisherName());
            vo.setTitle(notification.getTitle());
            vo.setContent(notification.getContent());

            // 处理图片列表
            if (notification.getImages() != null && !notification.getImages().isEmpty()) {
                vo.setImages(JSON.parseArray(notification.getImages(), String.class));
            } else {
                vo.setImages(new ArrayList<>());
            }

            vo.setIsUrgent(notification.getIsUrgent());
            vo.setRequireConfirmation(notification.getRequireConfirmation());
            vo.setTotalMembers(notification.getTotalMembers());
            vo.setConfirmedCount(notification.getConfirmedCount());
            vo.setIsConfirmed(isUserConfirmed(notificationId, currentUserType, currentUserId));
            vo.setCreateTime(notification.getCreateTime());
            vo.setUpdateTime(notification.getUpdateTime());

            // 获取发布者头像
            vo.setPublisherAvatar(getPublisherAvatar(notification.getPublisherType(), notification.getPublisherId()));

            // 获取队伍名称
            Teams team = teamsMapper.selectById(notification.getTeamId());
            vo.setTeamName(team != null ? team.getTeamName() : "");

            // 获取确认详情
            if (notification.getRequireConfirmation() == 1) {
                vo.setConfirmations(getConfirmationDetails(notificationId));
                vo.setUnconfirmedMembers(getUnconfirmedMembers(notification.getTeamId(), notificationId));
            } else {
                vo.setConfirmations(new ArrayList<>());
                vo.setUnconfirmedMembers(new ArrayList<>());
            }

            return vo;

        } catch (Exception e) {
            log.error("获取通知详情异常", e);
            return null;
        }
    }

    @Override
    @Transactional
    public String confirmNotification(NotificationConfirmVO confirmVO, Byte confirmerType, Long confirmerId, String confirmerName) {
        try {
            Notifications notification = getById(confirmVO.getNotificationId());
            if (notification == null || notification.getStatus() == 0) {
                return "通知不存在";
            }

            // 验证用户是否为队伍成员
            if (!isTeamMember(notification.getTeamId(), confirmerType, confirmerId)) {
                return "您不是该队伍成员，无法确认通知";
            }

            // 检查通知是否需要确认
            if (notification.getRequireConfirmation() == 0) {
                return "该通知不需要确认";
            }

            // 检查是否已经确认过
            if (isUserConfirmed(confirmVO.getNotificationId(), confirmerType, confirmerId)) {
                return "您已经确认过该通知";
            }

            // 创建确认记录
            NotificationConfirmations confirmation = new NotificationConfirmations();
            confirmation.setNotificationId(confirmVO.getNotificationId());
            confirmation.setTeamId(notification.getTeamId());
            confirmation.setConfirmerType(confirmerType);
            confirmation.setConfirmerId(confirmerId);
            confirmation.setConfirmerName(confirmerName);
            confirmation.setConfirmTime(LocalDateTime.now());
            confirmation.setRemark(confirmVO.getRemark());

            // 保存确认记录
            boolean saved = confirmationsMapper.insert(confirmation) > 0;

            if (saved) {
                // 更新通知的确认人数
                notification.setConfirmedCount(notification.getConfirmedCount() + 1);
                notification.setUpdateTime(LocalDateTime.now());
                updateById(notification);

                log.info("通知确认成功 - 通知ID: {}, 确认者: {} ({})",
                        confirmVO.getNotificationId(), confirmerName, confirmerType == 1 ? "教师" : "学生");
                return "确认成功";
            } else {
                return "确认失败";
            }

        } catch (Exception e) {
            log.error("确认通知异常", e);
            return "确认通知时发生错误：" + e.getMessage();
        }
    }

    @Override
    @Transactional
    public String deleteNotification(Long notificationId, Byte currentUserType, Long currentUserId) {
        try {
            Notifications notification = getById(notificationId);
            if (notification == null || notification.getStatus() == 0) {
                return "通知不存在";
            }

            // 只有发布者可以删除通知
            if (!notification.getPublisherType().equals(currentUserType) ||
                !notification.getPublisherId().equals(currentUserId)) {
                return "只有发布者可以删除通知";
            }

            // 软删除通知
            notification.setStatus((byte) 0);
            notification.setUpdateTime(LocalDateTime.now());
            boolean updated = updateById(notification);

            if (updated) {
                log.info("通知删除成功 - 通知ID: {}, 删除者: {} ({})",
                        notificationId, currentUserId, currentUserType == 1 ? "教师" : "学生");
                return "删除成功";
            } else {
                return "删除失败";
            }

        } catch (Exception e) {
            log.error("删除通知异常", e);
            return "删除通知时发生错误：" + e.getMessage();
        }
    }

    @Override
    public boolean isTeamMember(Long teamId, Byte userType, Long userId) {
        try {
            if (userType == 1) {
                // 教师：检查是否为指导老师或专家
                Teams team = teamsMapper.selectById(teamId);
                if (team != null && team.getInstructorId().equals(userId)) {
                    return true;
                }

                // 检查是否为入驻专家
                return teamExpertsMapper.checkExpertExists(teamId, userId) > 0;

            } else if (userType == 2) {
                // 学生：检查是否为队伍成员
                QueryWrapper<com.campusbackend.entity.TeamMembers> memberWrapper = new QueryWrapper<>();
                memberWrapper.eq("team_id", teamId)
                           .eq("student_id", userId)
                           .eq("join_status", 1);
                Long count = teamMembersMapper.selectCount(memberWrapper);
                return count != null && count > 0;
            }

            return false;

        } catch (Exception e) {
            log.error("验证队伍成员异常", e);
            return false;
        }
    }

    /**
     * 获取队伍总成员数（包括指导老师和专家）
     */
    private int getTotalTeamMembers(Long teamId) {
        try {
            // 统计学生成员数
            QueryWrapper<com.campusbackend.entity.TeamMembers> memberWrapper = new QueryWrapper<>();
            memberWrapper.eq("team_id", teamId).eq("join_status", 1);
            Long studentCountLong = teamMembersMapper.selectCount(memberWrapper);
            int studentCount = studentCountLong != null ? studentCountLong.intValue() : 0;

            // 指导老师（1个）
            int teacherCount = 1;

            // 统计专家数
            QueryWrapper<com.campusbackend.entity.TeamExperts> expertWrapper = new QueryWrapper<>();
            expertWrapper.eq("team_id", teamId).eq("join_status", 1);
            Long expertCountLong = teamExpertsMapper.selectCount(expertWrapper);
            int expertCount = expertCountLong != null ? expertCountLong.intValue() : 0;

            return studentCount + teacherCount + expertCount;

        } catch (Exception e) {
            log.error("统计队伍成员数异常", e);
            return 0;
        }
    }

    /**
     * 检查用户是否已确认通知
     */
    private boolean isUserConfirmed(Long notificationId, Byte userType, Long userId) {
        try {
            QueryWrapper<NotificationConfirmations> wrapper = new QueryWrapper<>();
            wrapper.eq("notification_id", notificationId)
                   .eq("confirmer_type", userType)
                   .eq("confirmer_id", userId);
            return confirmationsMapper.selectCount(wrapper) > 0;
        } catch (Exception e) {
            log.error("检查用户确认状态异常", e);
            return false;
        }
    }

    /**
     * 获取发布者头像
     */
    private String getPublisherAvatar(Byte publisherType, Long publisherId) {
        try {
            if (publisherType == 1) {
                Teachers teacher = teachersMapper.selectById(publisherId);
                return teacher != null ? teacher.getAvatar() : "";
            } else if (publisherType == 2) {
                Students student = studentsMapper.selectById(publisherId);
                return student != null ? student.getAvatar() : "";
            }
            return "";
        } catch (Exception e) {
            log.error("获取发布者头像异常", e);
            return "";
        }
    }

    /**
     * 获取确认详情列表
     */
    private List<NotificationDetailVO.ConfirmationInfo> getConfirmationDetails(Long notificationId) {
        try {
            QueryWrapper<NotificationConfirmations> wrapper = new QueryWrapper<>();
            wrapper.eq("notification_id", notificationId)
                   .orderByAsc("confirm_time");

            List<NotificationConfirmations> confirmations = confirmationsMapper.selectList(wrapper);

            return confirmations.stream().map(confirmation -> {
                NotificationDetailVO.ConfirmationInfo info = new NotificationDetailVO.ConfirmationInfo();
                info.setConfirmerType(confirmation.getConfirmerType());
                info.setConfirmerId(confirmation.getConfirmerId());
                info.setConfirmerName(confirmation.getConfirmerName());
                info.setConfirmTime(confirmation.getConfirmTime());
                info.setRemark(confirmation.getRemark());

                // 获取确认者头像
                info.setConfirmerAvatar(getPublisherAvatar(confirmation.getConfirmerType(), confirmation.getConfirmerId()));

                return info;
            }).collect(Collectors.toList());

        } catch (Exception e) {
            log.error("获取确认详情异常", e);
            return new ArrayList<>();
        }
    }

    /**
     * 获取未确认成员列表
     */
    private List<NotificationDetailVO.UnconfirmedMemberInfo> getUnconfirmedMembers(Long teamId, Long notificationId) {
        try {
            List<NotificationDetailVO.UnconfirmedMemberInfo> unconfirmedMembers = new ArrayList<>();

            // 获取所有已确认的成员ID
            QueryWrapper<NotificationConfirmations> confirmWrapper = new QueryWrapper<>();
            confirmWrapper.eq("notification_id", notificationId);
            List<NotificationConfirmations> confirmations = confirmationsMapper.selectList(confirmWrapper);

            Set<String> confirmedMemberKeys = confirmations.stream()
                    .map(c -> c.getConfirmerType() + "_" + c.getConfirmerId())
                    .collect(Collectors.toSet());

            // 获取队伍指导老师
            Teams team = teamsMapper.selectById(teamId);
            if (team != null) {
                String teacherKey = "1_" + team.getInstructorId();
                if (!confirmedMemberKeys.contains(teacherKey)) {
                    Teachers teacher = teachersMapper.selectById(team.getInstructorId());
                    if (teacher != null) {
                        NotificationDetailVO.UnconfirmedMemberInfo memberInfo = new NotificationDetailVO.UnconfirmedMemberInfo();
                        memberInfo.setMemberType((byte) 1);
                        memberInfo.setMemberId(teacher.getId());
                        memberInfo.setMemberName(teacher.getRealName());
                        memberInfo.setMemberAvatar(teacher.getAvatar());
                        memberInfo.setMemberRole("指导老师");
                        unconfirmedMembers.add(memberInfo);
                    }
                }
            }

            // 获取队伍学生成员
            QueryWrapper<com.campusbackend.entity.TeamMembers> memberWrapper = new QueryWrapper<>();
            memberWrapper.eq("team_id", teamId).eq("join_status", 1);
            List<com.campusbackend.entity.TeamMembers> teamMembers = teamMembersMapper.selectList(memberWrapper);

            for (com.campusbackend.entity.TeamMembers member : teamMembers) {
                String studentKey = "2_" + member.getStudentId();
                if (!confirmedMemberKeys.contains(studentKey)) {
                    Students student = studentsMapper.selectById(member.getStudentId());
                    if (student != null) {
                        NotificationDetailVO.UnconfirmedMemberInfo memberInfo = new NotificationDetailVO.UnconfirmedMemberInfo();
                        memberInfo.setMemberType((byte) 2);
                        memberInfo.setMemberId(student.getId());
                        memberInfo.setMemberName(student.getRealName());
                        memberInfo.setMemberAvatar(student.getAvatar());
                        memberInfo.setMemberRole(member.getMemberRole() != null ? member.getMemberRole() : "队员");
                        unconfirmedMembers.add(memberInfo);
                    }
                }
            }

            // 获取专家成员
            QueryWrapper<com.campusbackend.entity.TeamExperts> expertWrapper = new QueryWrapper<>();
            expertWrapper.eq("team_id", teamId).eq("join_status", 1);
            List<com.campusbackend.entity.TeamExperts> teamExperts = teamExpertsMapper.selectList(expertWrapper);

            for (com.campusbackend.entity.TeamExperts expert : teamExperts) {
                String expertKey = "1_" + expert.getExpertId();
                if (!confirmedMemberKeys.contains(expertKey)) {
                    Teachers teacher = teachersMapper.selectById(expert.getExpertId());
                    if (teacher != null) {
                        NotificationDetailVO.UnconfirmedMemberInfo memberInfo = new NotificationDetailVO.UnconfirmedMemberInfo();
                        memberInfo.setMemberType((byte) 1);
                        memberInfo.setMemberId(teacher.getId());
                        memberInfo.setMemberName(teacher.getRealName());
                        memberInfo.setMemberAvatar(teacher.getAvatar());
                        memberInfo.setMemberRole("入驻专家");
                        unconfirmedMembers.add(memberInfo);
                    }
                }
            }

            return unconfirmedMembers;

        } catch (Exception e) {
            log.error("获取未确认成员异常", e);
            return new ArrayList<>();
        }
    }
}
